<?php

declare(strict_types=1);

namespace App\Services;

use Hyperf\Di\Annotation\Inject;
use App\Exception\ApiException;
use App\Constants\ErrorCode;
use Hyperf\DbConnection\Db;
use App\Model\JiscarGift;
use App\Model\JiscarGiftCdk;
use App\Model\JiscarContent;
use App\Model\JiscarEcology;
use App\Model\JiscarLotteryRecord;
use App\Model\JiscarVotingRecord;
use App\Model\JiscarPlatform;

class JiscarService extends BaseService
{

    public function index()
    {
        $ip = get_client_ip();      //客户端ip

        $beginTime = date('Y-m-d 00:00:00');
        $endTime = date('Y-m-d 00:00:00', strtotime('+1 day'));

        $lotteryNum = $this->getLotteryNum($ip);      //获取抽奖次数
        // $lotteryNum = 10000;     //临时测试

        $gift = JiscarGift::query()->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(7)->get()->toArray();       //奖品列表
        $notLottery = ['id'=>0, 'name'=>'谢谢参与', 'image'=>env('HTTP_HOST').'/public/images/activity/xxcy.png'];
        $gift[] = $notLottery;

        $cyjj = JiscarContent::query()->where('type', 1)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($cyjj as $key=>$val)
        {
            $cyjj[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }
        $jqcz = JiscarContent::query()->where('type', 2)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($jqcz as $key=>$val)
        {
            $jqcz[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }
        $sjxg = JiscarContent::query()->where('type', 3)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($sjxg as $key=>$val)
        {
            $sjxg[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }
        $qwxj = JiscarContent::query()->where('type', 4)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($qwxj as $key=>$val)
        {
            $qwxj[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }
        $czjx = JiscarContent::query()->where('type', 5)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($czjx as $key=>$val)
        {
            $czjx[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }

        $hmxx = JiscarEcology::query()->where('type', 1)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($hmxx as $key=>$val)
        {
            $hmxx[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }
        $qlcz = JiscarEcology::query()->where('type', 2)->where('status', 1)->where('deleted', 0)->orderBy('id', 'DESC')->limit(10)->get()->toArray();
        foreach($qlcz as $key=>$val)
        {
            $qlcz[$key]['vote'] = $val['vote'] + $val['virtual_vote'];
        }

        $result = [
            'lottery_num' => $lotteryNum,
            'gift' => $gift,
            'cyjj' => $cyjj,
            'jqcz' => $jqcz,
            'sjxg' => $sjxg,
            'qwxj' => $qwxj,
            'czjx' => $czjx,
            'hmxx' => $hmxx,
            'qlcz' => $qlcz,
        ];
        return aes_encrypt($result);
    }

    public function getLotteryRecord()
    {
        $model = JiscarLotteryRecord::query()->select('ip','gift_id','created_at')->where('gift_id', '>', 0);      //中奖记录
        $list = $this->usePage($model)->toArray();
        foreach($list['data'] as $key=>$val)
        {
            $giftName = JiscarGift::query()->select('name')->where('id', $val['gift_id'])->first();
            $list['data'][$key]['gift']['name'] = $giftName['name'];
            $firstTwoChars = substr($val['ip'], 0, 2);
            $stars = '***';
            $list['data'][$key]['user'] = $firstTwoChars . $stars;
            $list['data'][$key]['ip'] = $firstTwoChars . $stars;

            $list['data'][$key]['time_ago'] = time_ago(strtotime($val['created_at']));
        }

        return aes_encrypt($list);
    }

    public function lottery()
    {
        if(date('Y-m-d H:i:s') >= '2023-12-01')
        {
            throw new ApiException(ErrorCode::WARNING, '抽奖活动已结束');
        }

        $ip = get_client_ip();      //客户端ip
        $currentHourBegin = date('Y-m-d H:00:00');
        $currentHourEnd = date('Y-m-d H:00:00', strtotime('+1 hour'));

        $lotteryNum = $this->getLotteryNum($ip);        //获取抽奖次数

        if($lotteryNum <= 0)
        {
            throw new ApiException(ErrorCode::WARNING, '抽奖次数不足');
        }

        $notLottery = ['id'=>0, 'name'=>'谢谢参与', 'image'=>env('HTTP_HOST').'/public/images/activity/xxcy.png', 'probability'=>9970, 'cdk'=>''];       //定义谢谢参与数组

        //每天中奖限制
        $lotteryRecordCnt = JiscarLotteryRecord::query()->where('gift_id', '>', 0)->whereBetween('created_at',[$currentHourBegin, $currentHourEnd])->count();      //中奖记录

        if($lotteryRecordCnt >= 4)  // 每小时4次中奖限制
        {
            JiscarLotteryRecord::query()->insert(['ip'=>$ip, 'gift_id'=>0]);
            // logger()->info('每小时4次中奖限制');
            return $notLottery;
        }

        $gift = JiscarGift::query()->where('status', 1)->where('deleted', 0)->limit(7)->get()->toArray();       //奖品列表
        $gift[] = $notLottery;

        // 计算每个奖品的中奖概率区间
        $probabilityRanges = [];
        $totalProbability = 0;
        foreach ($gift as $val) {
            $totalProbability += $val['probability'];
            $probabilityRanges[] = ['probability' => $totalProbability, 'index' => $val];
        }
        // 生成随机数
        $randomNumber = mt_rand(1, 10000); // 假设概率总和为 10000
        $resGift = [];
        foreach ($probabilityRanges as $range) {
            if ($randomNumber <= $range['probability']) {
                $resGift = $range['index'];
                break;
            }
        }

        unset($resGift['probability']);     //删除奖品信息中的概率字段

        if($resGift['id'] != 0)
        {
            $giftCdk = JiscarGiftCdk::query()->where('gift_id', $resGift['id'])->where('used', 0)->first();
            if($giftCdk)
            {
                $resGift['cdk'] = $giftCdk['cdk'];

                Db::beginTransaction();
                try{
                    JiscarGiftCdk::query()->where('id', $giftCdk['id'])->update(['used' => 1]);
                    JiscarLotteryRecord::query()->insert(['ip'=>$ip, 'gift_id'=>$resGift['id'], 'cdk'=>$resGift['cdk']]);

                    Db::commit();
                } catch(\Throwable $e){
                    Db::rollBack();
                    throw new ApiException(ErrorCode::ERROR, $e->getMessage());
                }
            }else{
                JiscarLotteryRecord::query()->insert(['ip'=>$ip, 'gift_id'=>0]);
                return $notLottery;
            }
        }else{
            JiscarLotteryRecord::query()->insert(['ip'=>$ip, 'gift_id'=>0]);
        }

        return $resGift;
    }

    public function voting(array $params)
    {
        if(date('Y-m-d H:i:s') >= '2023-12-01')
        {
            throw new ApiException(ErrorCode::WARNING, '大众投票已结束');
        }

        $params = aes_decrypt($params['data']);

        if(!$params['sign'])
        {
            throw new ApiException(ErrorCode::WARNING, '投票异常');
        }

        $time = time();
        $clientTime = strtotime($params['sign']);
        if(abs($time-$clientTime) > 10)
        {
            throw new ApiException(ErrorCode::WARNING, '投票异常！');
        }

        $ip = get_client_ip();      //客户端ip

        $votingContent = 10;      //默认每天内容赛道10票
        $votingEcology = 10;      //默认每天生态赛道10票
        $beginTime = date('Y-m-d 00:00:00');
        $endTime = date('Y-m-d 00:00:00', strtotime('+1 day'));

        $type = $params['type'];
        $allocationId = $params['allocation_id'];

        //投票次数检查
        $votingRecord = JiscarVotingRecord::query()->where('ip', $ip)->where('type', $type)->whereBetween('created_at',[$beginTime,$endTime])->count();
        if($type == 1)
        {
            if($votingRecord >= $votingContent)
            {
                throw new ApiException(ErrorCode::WARNING, '今日内容赛道投票次数已用尽');
            }
        }elseif($type == 2){
            if($votingRecord >= $votingEcology)
            {
                throw new ApiException(ErrorCode::WARNING, '今日生态赛道投票次数已用尽');
            }
        }

        if($type == 1)
        {
            $tmpContentType = JiscarContent::query()->select('type')->where('id', $allocationId)->first();

            $typeCount = [];
            $contentType = JiscarVotingRecord::query()->with('jiscar_content')->where('ip', $ip)->where('type', $type)->whereBetween('created_at',[$beginTime,$endTime])->get()->toArray();
            foreach($contentType as $val)
            {
                // 检查jiscar_content是否存在并且type字段是否设置
                if (isset($val['jiscar_content']) && isset($val['jiscar_content']['type'])) {
                    // 获取type值
                    $contentType = $val['jiscar_content']['type'];

                    // 如果这个type已经在$typeCount数组中，增加它的计数
                    if (isset($typeCount[$contentType])) {
                        $typeCount[$contentType]++;
                    } else {
                        // 如果这个type不在$typeCount数组中，初始化计数为1
                        $typeCount[$contentType] = 1;
                    }
                }
            }
            if(!empty($typeCount[$tmpContentType['type']]))
            {
                if($typeCount[$tmpContentType['type']] >= 2)
                {
                    throw new ApiException(ErrorCode::WARNING, '内容赛道单个奖项限投2票');
                }
            }
        }elseif($type == 2){
            $tmpEcologyType = JiscarEcology::query()->select('type')->where('id', $allocationId)->first();

            $typeCount = [];
            $contentType = JiscarVotingRecord::query()->with('jiscar_ecology')->where('ip', $ip)->where('type', $type)->whereBetween('created_at',[$beginTime,$endTime])->get()->toArray();
            foreach($contentType as $val)
            {
                // 检查jiscar_ecology是否存在并且type字段是否设置
                if (isset($val['jiscar_ecology']) && isset($val['jiscar_ecology']['type'])) {
                    // 获取type值
                    $ecologyType = $val['jiscar_ecology']['type'];

                    // 如果这个type已经在$typeCount数组中，增加它的计数
                    if (isset($typeCount[$ecologyType])) {
                        $typeCount[$ecologyType]++;
                    } else {
                        // 如果这个type不在$typeCount数组中，初始化计数为1
                        $typeCount[$ecologyType] = 1;
                    }
                }
            }
            if(!empty($typeCount[$tmpEcologyType['type']]))
            {
                if($typeCount[$tmpEcologyType['type']] >= 5)
                {
                    throw new ApiException(ErrorCode::WARNING, '生态赛道单个奖项限投5票');
                }
            }
        }

        $res = JiscarVotingRecord::query()->where('ip', $ip)->where('type', $type)->where('allocation_id', $allocationId)->whereBetween('created_at',[$beginTime,$endTime])->first();
        if($res)
        {
            throw new ApiException(ErrorCode::WARNING, '已投票');
        }

        $data['ip'] = $ip;
        $data['allocation_id'] = $allocationId;
        $data['type'] = $type;
        JiscarVotingRecord::query()->insert($data);

        if($type==1)
        {
            JiscarContent::query()->where('id', $allocationId)->increment('vote');
        }elseif($type==2){
            JiscarEcology::query()->where('id', $allocationId)->increment('vote');
        }

        return [];
    }
    
    //获取今天抽奖次数
    private function getLotteryNum($ip)
    {
        $lotteryNum = 0;        //默认抽奖次数

        $beginTime = date('Y-m-d 00:00:00');
        $endTime = date('Y-m-d 00:00:00', strtotime('+1 day'));

        //通过投票数得到抽奖次数
        $votingRecord = JiscarVotingRecord::query()->select('type')->where('ip', $ip)->whereBetween('created_at',[$beginTime,$endTime])->get()->toArray();          //投票记录
        $types = array_column($votingRecord, 'type');
        // 计算各类型的数量
        $typeCounts = array_count_values($types);
        // 获取 type 为 1 和 2 的数量
        $contentCount = $typeCounts[1] ?? 0;
        $ecologyCount = $typeCounts[2] ?? 0;
        if($contentCount >= 10)
        {
            $lotteryNum++;
        }
        if($ecologyCount >= 10)
        {
            $lotteryNum++;
        }
        $usedLotteryNum = JiscarLotteryRecord::query()->where('ip', $ip)->whereBetween('created_at',[$beginTime,$endTime])->count();          //抽奖记录
        $lotteryNum = $lotteryNum - $usedLotteryNum;

        return $lotteryNum;
    }

    public function getPlatform()
    {
        $typeArr = ['zhibo', 'zhuanti'];
        $list = JiscarPlatform::query()->get()->toArray();
        foreach($list as $val)
        {
            $platform[$typeArr[$val['type_id']]][] = $val;
        }

        return aes_encrypt($platform);
    }

}